/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"


#include "底层绘图/底层绘图框架.h"

#include "底层绘图/intern/Vulkan/buffer/Vk图像.h"
#include "底层绘图/intern/Vulkan/Vulkan框架.h"

#include "底层绘图/intern/Vulkan/线管/线管.h"
#include "底层绘图/intern/Vulkan/线管/着色器.h"

#include "UI/Widget.h"

#include "core/网格辅助计算.h"




void f_vg_setView(S_设备环境& ctx, vec2 xy, vec2 size) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	VkViewport view;
	view.x = xy.x;
	view.y = xy.y;
	view.width = size.x;
	view.height = size.y;
	view.minDepth = 0;
	view.maxDepth = 1;

	VkRect2D rect;
	rect.offset.x = xy.x;
	rect.offset.y = xy.y;
	rect.extent.width = size.x;
	rect.extent.height = size.y;

	vkCmdSetViewport(rt->m_命令缓存, 0, 1, &view);
	vkCmdSetScissor(rt->m_命令缓存, 0, 1, &rect);

}

void f_vg_setView(S_设备环境& ctx, const S_Viewport* 视口, const S_Rect2D* 裁剪) {
	auto* rt = f_vk_get绘图环境(ctx);
	vkCmdSetViewport(rt->m_命令缓存, 0, 1, (VkViewport*)视口);
	vkCmdSetScissor(rt->m_命令缓存, 0, 1, (VkRect2D*)裁剪);
}

void f_vg_set2DView(S_设备环境& ctx, S_Rect2Df rect, vec2* offset) {
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);

	auto vert = static_cast<S_VkArray缓存*>(ctx.m_几何图形->m_平面图形GPU缓存_顶点);
	auto index = static_cast<S_VkArray缓存*>(ctx.m_几何图形->m_平面图形GPU缓存_索引);

	static VkDeviceSize fuck{};
	vkCmdBindVertexBuffers(rt->m_命令缓存, 0, 1, &(vert->m_Data.m_Buf), &fuck);
	vkCmdBindIndexBuffer(rt->m_命令缓存, index->m_Data.m_Buf, 0, VK_INDEX_TYPE_UINT32);



	VkViewport view{};
	view.width = rect.extent.x;
	view.height = rect.extent.y;
	view.minDepth = 0;
	view.maxDepth = 1;

	VkRect2D scissor{};
	scissor.extent.width = rect.extent.x;
	scissor.extent.height = rect.extent.y;

	vkCmdSetViewport(rt->m_命令缓存, 0, 1, &view);
	vkCmdSetScissor(rt->m_命令缓存, 0, 1, &scissor);
	vkCmdSetDepthBias(rt->m_命令缓存, 0, 0, 0);

	VkSampleLocationsInfoEXT sampleLocationsInfo = {};
	sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
	
	sampleLocationsInfo.sampleLocationGridSize = {1, 1}; // 网格大小
	
	if (offset && 0) {
		VkSampleLocationEXT locations[4] = {
			{0.25f, 0.25f},
			{0.75f, 0.25f},
			{0.25f, 0.75f},
			{0.75f, 0.75f}  // 远离像素边缘的中心区域分布
		};

		sampleLocationsInfo.pSampleLocations = (VkSampleLocationEXT*)locations;
		sampleLocationsInfo.sampleLocationsPerPixel = VK_SAMPLE_COUNT_4_BIT;
		sampleLocationsInfo.sampleLocationsCount = 4;
	}
	else {
		static VkSampleLocationEXT location{};
		sampleLocationsInfo.sampleLocationsPerPixel = VK_SAMPLE_COUNT_1_BIT;
		sampleLocationsInfo.pSampleLocations = &location;
		sampleLocationsInfo.sampleLocationsCount = 1;
	}
	//rf->vkCmdSetSampleLocationsEXT(rt->m_命令缓存, &sampleLocationsInfo);
}

void f_vg_setScissor(S_设备环境& ctx, const S_Rect2D* 裁剪) {
	auto* rt = f_vk_get绘图环境(ctx);
	vkCmdSetScissor(rt->m_命令缓存, 0, 1, (VkRect2D*)裁剪);
}


void f_vg_begin(S_UI渲染环境& ctx, C_Widget管理* gm, vec2 offset) {
	auto* rf = f_vk_get绘图框架(ctx.m_Ctx);
	auto* rt = f_vk_get绘图环境(ctx.m_Ctx);
	
	Mat44f proj[2];
	proj[0] = f_mat4_Ortho(0, gm->视口.width, 0, gm->视口.height, -10.0, 10.0);
	proj[1] = f_mat4_Ortho(offset.x, gm->视口.width + offset.x, offset.y, gm->视口.height + offset.y, -10.0, 10.0);
	//proj[1] = f_mat4_Ortho(offset.x, gm->视口.width, offset.y, gm->视口.height, -10.0, 10.0);
	f_fill板载缓存(gm->m_投影矩阵, {proj[0], proj[1]});


	VkWriteDescriptorSet writes[10] = {};

	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[0].pNext = nullptr;
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[0].dstArrayElement = 0;
	writes[0].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_Proj);
	writes[0].descriptorCount = 1;
	writes[0].pBufferInfo = &f_vk_get缓存信息(gm->m_投影矩阵);
	writes[0].dstBinding = 0;

	writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[1].pNext = nullptr;
	writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[1].dstArrayElement = 0;
	writes[1].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_WidgetTranform);
	writes[1].descriptorCount = 1;
	writes[1].pBufferInfo = &f_vk_get缓存信息(ctx.m_Ctx.m_几何图形->m_2D面板变换G);
	writes[1].dstBinding = 1;

	writes[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[2].pNext = nullptr;
	writes[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[2].dstArrayElement = 0;
	writes[2].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_WidgetTranform);
	writes[2].descriptorCount = 1;
	writes[2].pBufferInfo = &f_vk_get缓存信息(ctx.m_Ctx.m_几何图形->m_2D面板变换L);
	writes[2].dstBinding = 2;

	writes[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[3].pNext = nullptr;
	writes[3].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[3].dstArrayElement = 0;
	writes[3].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_WidgetColor);
	writes[3].descriptorCount = 1;
	writes[3].pBufferInfo = &f_vk_get缓存信息(ctx.m_Ctx.m_几何图形->m_2D面板颜色);
	writes[3].dstBinding = DEF_binding_RectColor;

	writes[4].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[4].pNext = nullptr;
	writes[4].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[4].dstArrayElement = 0;
	writes[4].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_WidgetConvexRect);
	writes[4].descriptorCount = 1;
	writes[4].pBufferInfo = &f_vk_get缓存信息(ctx.m_Ctx.m_几何图形->m_2D凸包图元属性);
	writes[4].dstBinding = DEF_binding_ConvexRect;

	writes[5].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[5].pNext = nullptr;
	writes[5].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[5].dstArrayElement = 0;
	writes[5].dstSet = f_VkDescriptorSet(gm->m_DS_累积, 4);
	writes[5].descriptorCount = 1;
	writes[5].pBufferInfo = &f_vk_get缓存信息(gm->m_UICtx->m_层区域属性);
	writes[5].dstBinding = DEF_binding_L4_LayerArea;

	writes[6].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[6].pNext = nullptr;
	writes[6].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[6].dstArrayElement = 0;
	writes[6].dstSet = f_VkDescriptorSet(gm->m_DS_累积, 4);
	writes[6].descriptorCount = 1;
	writes[6].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	writes[6].dstBinding = DEF_binding_L4_SampleAA;

	writes[7].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[7].pNext = nullptr;
	writes[7].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[7].dstArrayElement = 0;
	writes[7].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_FS_TAA);
	writes[7].descriptorCount = 1;
	writes[7].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	writes[7].dstBinding = DEF_binding_L4_SampleAA;

	f_纹理槽_设置GPU参数(ctx.m_纹理槽, writes[8], f_vk_get着色参数设置(rf->m_管线参数设置_FS_Textures), 0);
	f_纹理槽_设置GPU参数(ctx.m_纹理槽, writes[9], f_vk_get着色参数设置(rf->m_管线参数设置_FS_Textures), 1);

	vkUpdateDescriptorSets(rt->m_设备, 10, writes, 0, nullptr);

}

void f_vg_begin(C_Widget管理* gm, vec2 offset) {
	auto& ctx = gm->m_UICtx->m_Ctx;
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);

	Mat44f proj[2];
	proj[0] = f_mat4_Ortho(0, gm->视口.width, 0, gm->视口.height, -10.0, 10.0);
	proj[1] = f_mat4_Ortho(offset.x, gm->视口.width + offset.x, offset.y, gm->视口.height + offset.y, -10.0, 10.0);
	f_fill板载缓存(gm->m_投影矩阵, {proj[0], proj[1]});


	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_合成写入纹理集, 0, DEF_binding_L3_ArrayImage);
	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_合成采样纹理集, 1, DEF_binding_L3_ArraySampler);


	C_VkDescriptorSet* ds = static_cast<C_VkDescriptorSet*>(gm->m_UICtx->m_DS_UI图层纹理混合);
	VkWriteDescriptorSet writes[7] = {};

	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[0].pNext = nullptr;
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[0].dstArrayElement = 0;
	writes[0].dstSet = ds->m_DS[0];
	writes[0].descriptorCount = 1;
	writes[0].pBufferInfo = &f_vk_get缓存信息(gm->m_投影矩阵);
	writes[0].dstBinding = 0;

	writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[1].pNext = nullptr;
	writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[1].dstArrayElement = 0;
	writes[1].dstSet = ds->m_DS[1];
	writes[1].descriptorCount = 1;
	writes[1].pBufferInfo = &f_vk_get缓存信息(ctx.m_几何图形->m_2D面板变换G);
	writes[1].dstBinding = 1;

	writes[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[2].pNext = nullptr;
	writes[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[2].dstArrayElement = 0;
	writes[2].dstSet = ds->m_DS[1];
	writes[2].descriptorCount = 1;
	writes[2].pBufferInfo = &f_vk_get缓存信息(ctx.m_几何图形->m_2D面板变换L);
	writes[2].dstBinding = 2;

	f_纹理槽_设置纹理读写(gm->m_合成纹理绑定槽, writes[3], ds->m_DS[3], 0);
	f_纹理槽_设置GPU参数(gm->m_合成纹理绑定槽, writes[4], ds->m_DS[3], 1);

	//writes[5].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	//writes[5].pNext = nullptr;
	//writes[5].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	//writes[5].dstArrayElement = 0;
	//writes[5].dstSet = ds->m_DS[4];
	//writes[5].descriptorCount = 1;
	//writes[5].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	//writes[5].dstBinding = DEF_binding_L4_SampleAA;

	writes[5].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[5].pNext = nullptr;
	writes[5].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[5].dstArrayElement = 0;
	writes[5].dstSet = ds->m_DS[4];
	writes[5].descriptorCount = 1;
	writes[5].pBufferInfo = &f_vk_get缓存信息(gm->m_UICtx->m_层区域属性);
	writes[5].dstBinding = DEF_binding_L4_LayerArea;

	writes[6].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[6].pNext = nullptr;
	writes[6].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[6].dstArrayElement = 0;
	writes[6].dstSet = ds->m_DS[4];
	writes[6].descriptorCount = 1;
	writes[6].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	writes[6].dstBinding = DEF_binding_L4_SampleAA;

	vkUpdateDescriptorSets(rt->m_设备, 7, writes, 0, nullptr);

}

void f_vg_render2(S_设备环境& ctx, S_2D画布& 画布, E_管线槽 管线槽) {
	for (auto& e : 画布.m_绘制元素) {
		f_vg_render2(ctx, *e, 管线槽);
	}
}

void f_vg_render2(S_设备环境& ctx, S_Surface2D& surf, E_管线槽 管线槽) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	switch (surf.m_绘制类型) {
		case S_元素绘制类型::e_绘制类型_序列: {
			auto& m = surf.m_平面形状;
			if(m.m_Mem.m_数量) break;
			return;
		}
		case S_元素绘制类型::e_绘制类型_无顶点索引: {
			if(surf.m_顶点数量) break;
			return;
		}
		case S_元素绘制类型::e_绘制类型_间接: {
			if(surf.m_间接.m_Mem.m_数量) break;
			return;
		}
		case S_元素绘制类型::e_绘制类型_间接索引: {
			if(surf.m_间接.m_Mem.m_数量) break;
			return;
		}
		default:
			return;
	}

	
	S_Vk着色* shader = f_pipeline_绑定管线(rt->m_命令缓存, surf.m_多维材质槽.m_Material, 管线槽);
	
	surf.mf_参数设置回调(ctx, surf);
	
	vkCmdPushConstants(rt->m_命令缓存,
					   shader->m_线管布局,
					   f_vk_get参数布局着色阶段(surf.m_常量推送.m_常量推送绑定阶段),
					   0,
					   surf.m_常量推送.m_常量推送字节大小,
					   surf.m_常量推送.m_常量推送);

	
	
	
	VkDescriptorSet* s = shader->m_DS.data();
	uint32 描述数量 = shader->m_DS.size();


	vkCmdBindDescriptorSets(rt->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->m_线管布局, 0, 描述数量, s, 0, 0);
	vkCmdSetLineWidth(rt->m_命令缓存, surf.m_线宽);
	
	
	switch (surf.m_绘制类型) {
		case S_元素绘制类型::e_绘制类型_序列: {
			auto& m = surf.m_平面形状;
			vkCmdDraw(rt->m_命令缓存, m.m_Mem.m_数量, 1, m.m_Mem.m_偏移, 0);
			break;
		}
		case S_元素绘制类型::e_绘制类型_无顶点索引: {
			vkCmdDraw(rt->m_命令缓存, surf.m_顶点数量, 1, 0, 0);
			break;
		}
		case S_元素绘制类型::e_绘制类型_间接: {
			vkCmdDrawIndirect(rt->m_命令缓存, 
									 f_vk_get缓存对象(surf.m_间接), 
									 surf.m_间接.m_Mem.m_偏移 * sizeof(S_VkDrawIndirectCommand), 
									 surf.m_间接.m_Mem.m_数量,
									 sizeof(S_VkDrawIndirectCommand));
			break;
		}
		case S_元素绘制类型::e_绘制类型_间接索引: {
			vkCmdDrawIndexedIndirect(rt->m_命令缓存, 
									f_vk_get缓存对象(surf.m_间接), 
									surf.m_间接.m_Mem.m_偏移 * sizeof(S_VkDrawIndexedIndirectCommand), 
									surf.m_间接.m_Mem.m_数量,
									sizeof(S_VkDrawIndexedIndirectCommand));
			break;
		}
		default:
			break;
	}

}





static void f_drawImage_参数设置(S_设备环境& ctx, S_Surface2D& surf) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	VkWriteDescriptorSet writes[2]{};

	for (uint32 i = 0; i < surf.m_纹理槽.m_槽数量; ++i) {
		f_纹理槽_设置GPU参数(surf.m_纹理槽, writes[i], f_vk_get着色参数设置(rf->m_管线参数设置_FS_1Tex), i);
	}

	vkUpdateDescriptorSets(rt->m_设备, 1, writes, 0, NULL);
}
S_Surface2D* f_vg_genImage(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	auto surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);

	surf->m_画布变换 = &画布.m_变换;
	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_图像[混合模式];
	//设置绘制回调函数
	surf->mf_参数设置回调 = f_drawImage_参数设置;
	f_df_创建常量推送<S_ConstPush_Texture>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	surf->m_纹理槽 = f_纹理槽_创建(1);
	
	surf->m_平面形状 = ctx.m_几何图形->m_平面矩形;
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_序列;
	return surf;
}
void f_vg_drawImage(S_设备环境& ctx, S_Surface2D& surf, S_纹理* tex, S_Rect2Df rect) {
	f_纹理槽_设置纹理(surf.m_纹理槽, tex, 10, 0);

	auto& push = f_df_推送常量<S_ConstPush_Texture>(surf.m_常量推送);

	push = {0, 
			uint32(surf.m_画布变换->m_Mem.m_偏移), 
			rect.offset.x, rect.offset.y, 
			rect.extent.x, rect.extent.y
			};
	
}


static void f_drawRect_参数设置(S_设备环境& ctx, S_Surface2D& surf) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	VkWriteDescriptorSet writes[2]{};

	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[0].pNext = nullptr;
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[0].dstArrayElement = 0;
	writes[0].dstBinding = 1;
	writes[0].dstSet = f_vk_get着色参数设置(rf->m_管线参数设置_VS_Mat4);
	writes[0].descriptorCount = 1;

	vkUpdateDescriptorSets(rt->m_设备, 1, writes, 0, NULL);
}
S_Surface2D* f_vg_genRect(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	auto surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);

	surf->m_画布变换 = &画布.m_变换;
	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_图像[混合模式];
	//设置绘制回调函数
	surf->mf_参数设置回调 = f_drawImage_参数设置;
	f_df_创建常量推送<S_ConstPush_Texture>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	surf->m_纹理槽 = f_纹理槽_创建(1);

	surf->m_平面形状 = ctx.m_几何图形->m_平面矩形;
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_序列;
	return surf;
}

void f_vg_drawRect(S_设备环境& ctx, S_Surface2D& surf, S_纹理* tex, S_Rect2Df rect) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);


}





////画UI合成
//S_Surface2D* f_vg_genComposition(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
//	auto* rt = f_vk_get绘图环境(ctx);
//
//	auto surf = f_surface2D_alloc(ctx);
//	画布.m_绘制元素.emplace_back(surf);
//
//	surf->m_画布变换 = &画布.m_变换;
//
//
//	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_序列;
//	return surf;
//}
//
//void f_vg_drawComposition(S_Surface2D& surf, std::vector<mat2>& 层) {
//
//}



static void f_drawComposition_参数设置(S_设备环境& ctx, S_Surface2D& surf) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	S_ConstPush_TAA& push = f_df_推送常量<S_ConstPush_TAA>(surf.m_常量推送);
	
}
S_Surface2D* f_vg_genComposition(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
	auto* rt = f_vk_get绘图环境(ctx);
	//auto* rf = f_vk_get绘图框架(ctx);

	auto surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);
	f_df_创建常量推送<S_ConstPush_TAA>(surf->m_常量推送, E_着色阶段::e_顶点着色);

	surf->m_画布变换 = &画布.m_变换;
	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_图像合成;

	//设置绘制回调函数
	surf->mf_参数设置回调 = f_drawComposition_参数设置;
	surf->m_纹理槽 = f_纹理槽_创建(1);
	
	surf->m_平面形状 = ctx.m_几何图形->m_平面矩形;
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_序列;

	return surf;
}

void f_vg_setComposition(S_设备环境& ctx, S_Surface2D& surf, uint32 层, uint32 层数量, S_Rect2Df rect) {
	S_ConstPush_TAA& push = f_df_推送常量<S_ConstPush_TAA>(surf.m_常量推送);
	push.m_Width_Size = rect.extent.x;
	push.m_Hight_Size = rect.extent.y;
	push.x = rect.offset.x;
	push.y = rect.offset.y;

	push.m_Offset_TranformG = uint32(surf.m_画布变换->m_Mem.m_偏移);
	push.m_LayerAttr = f_widget_UI层属性(层, 层数量);
}

void f_vg_render(S_UI渲染环境& uiCtx, S_2D画布& 画布, E_管线槽 管线槽) {
	auto& ctx = uiCtx.m_Ctx;
	auto* rt = f_vk_get绘图环境(ctx);
	//auto* rf = f_vk_get绘图框架(ctx);

	for (auto& e : 画布.m_绘制元素) {

		e->mf_参数设置回调(ctx, *e);
		uiCtx.m_DS_UI图层纹理混合->f_bind(e->m_常量推送);

		switch (e->m_绘制类型) {
			case S_元素绘制类型::e_绘制类型_序列: {
				auto& m = e->m_平面形状;
				vkCmdDraw(rt->m_命令缓存, m.m_Mem.m_数量, 1, m.m_Mem.m_偏移, 0);
				break;
			}
			case S_元素绘制类型::e_绘制类型_无顶点索引: {
				vkCmdDraw(rt->m_命令缓存, e->m_顶点数量, 1, 0, 0);
				break;
			}
			case S_元素绘制类型::e_绘制类型_间接: {
				vkCmdDrawIndirect(rt->m_命令缓存, 
								  f_vk_get缓存对象(e->m_间接), 
								  e->m_间接.m_Mem.m_偏移 * sizeof(S_VkDrawIndirectCommand), 
								  e->m_间接.m_Mem.m_数量,
								  sizeof(S_VkDrawIndirectCommand));
				break;
			}
			case S_元素绘制类型::e_绘制类型_间接索引: {
				vkCmdDrawIndexedIndirect(rt->m_命令缓存, 
										 f_vk_get缓存对象(e->m_间接), 
										 e->m_间接.m_Mem.m_偏移 * sizeof(S_VkDrawIndexedIndirectCommand), 
										 e->m_间接.m_Mem.m_数量,
										 sizeof(S_VkDrawIndexedIndirectCommand));
				break;
			}
			default:
				break;
		}
	}
}









void f_vg_CompositionBegin(S_GPU计算* ctx) {
	auto df = f_vk_get绘图框架(ctx->m_Ctx);
	auto dc = f_vk_get绘图环境(ctx->m_Ctx);

	VkResult result;

	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;


	result = vkResetCommandBuffer(dc->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(dc->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);


}
void f_vg_Composition(S_Surface3D** face, uint32 num) {
	auto df = f_vk_get绘图框架(*face[0]->m_Ctx);
	auto dc = f_vk_get绘图环境(*face[0]->m_Ctx);
	
	VkDevice 设备 = f_vk_getDevice(*face[0]->m_Ctx);


	for (uint32 i = 0; i < num; ++i) {
		f_纹理集_刷新所有纹理信息(face[i]->m_平面绑定纹理集);
		f_纹理槽_设置纹理集(face[i]->m_合成纹理绑定槽, face[i]->m_平面绑定纹理集, 0, DEF_binding_L3_ArrayImage);

		auto shader = static_cast<S_Vk着色*>(dc->m_2D渲染管线->m_计算管线_图像合成->m_Shader);
		//auto& push = dc->m_2D渲染管线->m_计算管线_图像合成->m_推送常量;

		C_VkDescriptorSet* ds = static_cast<C_VkDescriptorSet*>(face[i]->m_DS);
		VkWriteDescriptorSet writes[2] = {};

		f_纹理槽_设置GPU参数(face[i]->m_合成纹理绑定槽, writes[0], ds->m_DS[0], 0);
		

		S_推送常量 常量;
		f_df_创建常量推送<S_ConstPush_TAA>(常量, E_着色阶段::e_计算着色);

		face[i]->m_DS->f_bind(常量);

		auto dim = face[i]->m_Color[i]->m_Size / 16;
		vkCmdDispatch(dc->m_命令缓存, dim.x, dim.y, dim.z);
	}
	
}

void f_vg_end(S_设备环境& ctx, uint32 列队) {
	//auto df = f_vk_get绘图框架(ctx->m_Ctx);
	auto dc = f_vk_get绘图环境(ctx);

	VkDevice 设备 = f_vk_getDevice(ctx);

	VkResult result;
	result = vkEndCommandBuffer(dc->m_命令缓存);
	assert(result == VK_SUCCESS);


	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = &dc->m_命令缓存;
	
	
	result = vkQueueSubmit(dc->m_图形列队[列队], 1, &命令提交信息, dc->m_同步围栏);
	do {
		result = vkWaitForFences(设备, 1, &dc->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkResetFences(设备, 1, &dc->m_同步围栏);
}



void f_vg_Blur(C_Widget管理* gm, uvec2 分辨率, uint8 layerID) {
	auto rf = f_vk_get绘图框架(gm->m_UICtx->m_Ctx);
	auto rt = f_vk_get绘图环境(gm->m_UICtx->m_Ctx);

	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_模糊写入纹理集, 0, DEF_binding_L3_ArrayImage);
	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_模糊采样纹理集, 1, DEF_binding_L3_ArraySampler);

	C_VkDescriptorSet* ds = static_cast<C_VkDescriptorSet*>(gm->m_DS_模糊);
	VkWriteDescriptorSet writes[3] = {};

	f_纹理槽_设置纹理读写(gm->m_合成纹理绑定槽, writes[0], ds->m_DS[3], 0);
	f_纹理槽_设置GPU参数(gm->m_合成纹理绑定槽, writes[1], ds->m_DS[3], 1);

	writes[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[2].pNext = nullptr;
	writes[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[2].dstArrayElement = 0;
	writes[2].dstSet = ds->m_DS[4];
	writes[2].descriptorCount = 1;
	writes[2].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	writes[2].dstBinding = DEF_binding_L4_SampleAA;

	vkUpdateDescriptorSets(rt->m_设备, 3, writes, 0, nullptr);

	
	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;

	VkResult result;
	result = vkResetCommandBuffer(rt->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(rt->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);



	auto& push = f_df_推送常量<S_ConstPush_TAA>(gm->m_合成常量参数);
	push.m_LayerAttr = f_widget_UI层属性(layerID, gm->m_帧渲染层.size());
	gm->m_DS_模糊->f_bind(gm->m_合成常量参数);


	uvec3 dim = _uVec3(gm->m_模糊纹理大小/16,1);
	vkCmdDispatch(rt->m_命令缓存, dim.x, dim.y, dim.z);

	f_vg_end(gm->m_UICtx->m_Ctx, 0);
}


void f_vg_Accumulate(C_Widget管理* gm, uvec2 分辨率, uint8 layerID) {
	auto rf = f_vk_get绘图框架(gm->m_UICtx->m_Ctx);
	auto rt = f_vk_get绘图环境(gm->m_UICtx->m_Ctx);
	auto* a = &gm->m_合成纹理绑定槽;
	a->m_槽数量;

	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_合成写入纹理集, 0, DEF_binding_L3_ArrayImage);
	f_纹理槽_设置纹理集(gm->m_合成纹理绑定槽, gm->m_合成采样纹理集, 1, DEF_binding_L3_ArraySampler);

	C_VkDescriptorSet* ds = static_cast<C_VkDescriptorSet*>(gm->m_DS_累积);
	VkWriteDescriptorSet writes[3] = {};

	f_纹理槽_设置纹理读写(gm->m_合成纹理绑定槽, writes[0], ds->m_DS[3], 0);
	f_纹理槽_设置GPU参数(gm->m_合成纹理绑定槽, writes[1], ds->m_DS[3], 1);

	writes[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[2].pNext = nullptr;
	writes[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[2].dstArrayElement = 0;
	writes[2].dstSet = ds->m_DS[4];
	writes[2].descriptorCount = 1;
	writes[2].pBufferInfo = &f_vk_get缓存信息(gm->m_采样属性);
	writes[2].dstBinding = DEF_binding_L4_SampleAA;

	vkUpdateDescriptorSets(rt->m_设备, 3, writes, 0, nullptr);


	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;

	VkResult result;
	result = vkResetCommandBuffer(rt->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(rt->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);



	auto& push = f_df_推送常量<S_ConstPush_TAA>(gm->m_合成常量参数);
	push.m_LayerAttr = f_widget_UI层属性(layerID, gm->m_帧渲染层.size());
	ds->f_bind(gm->m_合成常量参数);


	uvec3 dim = _uVec3(分辨率.x/16 + 1, 分辨率.y/16 + 1, 1);
	vkCmdDispatch(rt->m_命令缓存, dim.x, dim.y, dim.z);

	f_vg_end(gm->m_UICtx->m_Ctx, 0);
}









